package com.core.mvc.config;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ConfigParser
{
	private static ConfigParser parser;
	private ConfigBean config;

	private ConfigParser()
	{

	}

	public static ConfigParser getParser()
	{
		if ( parser == null )
		{
			synchronized ( ConfigParser.class )
			{
				if ( parser == null )
				{
					parser = new ConfigParser();
				}
			}
		}
		return parser;
	}

	public ConfigBean parse()
	{
		if ( config == null )
		{
			config = doParse();
		}
		return config;
	}

	public ConfigBean reParse()
	{
		config = doParse();
		return config;
	}

	private ConfigBean doParse()
	{
		ConfigBean config = new ConfigBean();
		// 创建一个DocumentBuilderFactory的对象
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 创建一个DocumentBuilder的对象
		try
		{
			// 创建DocumentBuilder对象
			DocumentBuilder db = dbf.newDocumentBuilder();
			// 通过DocumentBuilder对象的parser方法加载config.xml文件到当前项目下
			Document document = db.parse(
							getClass().getClassLoader().getResourceAsStream( "config.xml" ) );
			NodeList cfg = document.getElementsByTagName( "mvc-config" );
			if ( cfg.getLength() > 0 )
			{
				NodeList childrens = cfg.item( 0 ).getChildNodes();
				for ( int i = 0; i < childrens.getLength(); i++ )
				{
					Node children = childrens.item( i );
					if ( children.getNodeName().equals( "initialize" ) )
					{
						parseInitialize( children, config );
					}
					else if ( children.getNodeName().equals( "database" ) )
					{
						parseDatabase( children, config );
					}
				}
			}
		}
		catch ( Exception e )
		{
			e.printStackTrace();
		}
		return config;
	}

	/**
	 * 解析服务配置
	 * 
	 * @param init
	 * @param config
	 */
	private void parseInitialize( Node init, ConfigBean config )
	{
		NodeList initChildren = init.getChildNodes();
		InitConfig initialize = new InitConfig();
		for ( int i = 0; i < initChildren.getLength(); i++ )
		{
			Node children = initChildren.item( i );
			if ( children.getNodeName().equals( "scanPath" ) )
			{
				initialize.addScanPath( getNodeValue( children ) );
			}
			else if ( children.getNodeName().equals( "charset" ) )
			{
				initialize.setCharset( getNodeValue( children ) );
			}
		}
		config.setInit( initialize );
	}

	/**
	 * 解析数据库配置
	 * 
	 * @param db
	 * @param config
	 */
	private void parseDatabase( Node db, ConfigBean config )
	{
		NodeList dbChildren = db.getChildNodes();
		DBConfig database = new DBConfig();
		for ( int i = 0; i < dbChildren.getLength(); i++ )
		{
			Node children = dbChildren.item( i );
			if ( children.getNodeName().equals( "driver" ) )
			{
				database.setDriver( getNodeValue( children ) );
			}
			else if ( children.getNodeName().equals( "url" ) )
			{
				database.setUrl( getNodeValue( children ) );
			}
			else if ( children.getNodeName().equals( "user" ) )
			{
				database.setUser( getNodeValue( children ) );
			}
			else if ( children.getNodeName().equals( "passwd" ) )
			{
				database.setPasswd( getNodeValue( children ) );
			}
			else if ( children.getNodeName().equals( "initConnSize" ) )
			{
				database.setInitConnSize( getIntNodeValue( children ) );
			}
			else if ( children.getNodeName().equals( "incrementalConnSize" ) )
			{
				database.setIncrementalConnSize( getIntNodeValue( children ) );
			}
			else if ( children.getNodeName().equals( "maxConnSize" ) )
			{
				database.setMaxConnSize( getIntNodeValue( children ) );
			}
		}
		config.setDatabase( database );
	}

	/**
	 * 获取节点值
	 * 
	 * @param node
	 * @return
	 */
	private String getNodeValue( Node node )
	{
		try
		{
			if ( node.getNodeType() == Node.ELEMENT_NODE || node.getNodeType() == Node.TEXT_NODE )
			{
				return node.getFirstChild().getNodeValue().trim();
			}
		}
		catch ( Exception e )
		{
			e.printStackTrace();
		}
		return null;
	}

	public int getIntNodeValue( Node node )
	{
		int ret = 0;
		String str = getNodeValue( node );
		if ( str != null )
		{
			try
			{
				ret = Integer.parseInt( str );
			}
			catch ( Exception e )
			{
				e.printStackTrace();
			}
		}
		return ret;
	}

	/**
	 * 获取节点属性值
	 * 
	 * @param node
	 * @param attrName
	 * @return
	 */
	private String getNodeAttrsValue( Node node, String attrName )
	{
		NamedNodeMap attrs = node.getAttributes();
		Node attr = null;
		for ( int j = 0; j < attrs.getLength(); j++ )
		{
			attr = attrs.item( j );
			if ( attr.getNodeName().equals( attrName ) )
			{
				return attr.getNodeValue();
			}
		}
		return null;
	}

	public static void main( String[] argv )
	{
		ConfigParser.getParser().parse();
	}
}
